package mk.company.fin.importer;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractImporter {
	
	private static final Logger LOG = LoggerFactory.getLogger(AbstractImporter.class);
	public static final String CONTENTSPLITTER = ";";
	
	private int columnsCount;
	private transient int importedLinesCounter;
	
	protected AbstractImporter(int columnsCount) {
		this.columnsCount = columnsCount;
	}
	

	/**
	 * Tries to import the content (represented with the input stream) as
	 * the given type. The importing is done line by line with the 
	 * {@link AbstractImporter#CONTENTSPLITTER} as splitter.<br/>
	 * <b>NOTE:</b> The input stream must be UTF-8 encoded.
	 * @param type the type of the content
	 * @return true if all lines passed
	 */
	public boolean importContent(InputStream inputStream) {
		boolean result = true;
		System.out.println("ImportContent");
		// validation
		if (inputStream == null) {
			result = false;
			
		} else {
			synchronized (AbstractImporter.class) {
				result = importContentInternal(inputStream);
			}
		}
		
		// result
		return result;
	}


	private boolean importContentInternal(InputStream inputStream) {
		// log
		LOG.debug("RUNNING...");
		boolean result = true;
		
		// init
		try {
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
			importedLinesCounter = 0;
			String line = "";
			
			while ((line = bufferedReader.readLine()) != null) {
				String[] parts = line.split(CONTENTSPLITTER);
				if (parts.length == getColumnsCount()) {
					String errorMessage = importLine(parts);
					if (StringUtils.isNotEmpty(errorMessage)) {
						LOG.error(errorMessage);
						result = false;
					}
				}
				
				// count
				importedLinesCounter++;
				if (importedLinesCounter % 50 == 0) {
					LOG.debug(importedLinesCounter + " imports executed...");
				}
			}
		} catch (Exception e) {
			LOG.error("The error ocures while importing!", e);
			result = false;
		}
		
		LOG.debug("DONE");
		return result;
	}
	
	/**
	 * Tries to import the line (represented with contents).
	 * @param contents the line contents
	 * @return the error message if the importing fails
	 */
	protected abstract String importLine(String... contents);


	public int getColumnsCount() {
		return columnsCount;
	}

	public int getImportedLinesCounter() {
		return importedLinesCounter;
	}

}
